import datetime

from django import template
from django.template import RequestContext
from django.http import HttpResponseRedirect, HttpResponse, Http404
from django.shortcuts import render_to_response, get_object_or_404
from django.core.exceptions import ObjectDoesNotExist
from django.contrib.auth.decorators import login_required
from django.contrib.auth import logout
from django.contrib.auth.models import User
from datetime import datetime, timedelta

# Aqui se importa los compiladores
from oca.compiler.python.pycompiler import PyCompiler
from oca.compiler.java.javacompiler import JavaCompiler

from oca.forms import RegistrationForm, PasswordChangeForm
from oca.models import *
from oca.queries import is_registered_to_contest, has_time, lef_time
from oca.models import Competencia, Problema, Solucion, Puntaje, Lenguaje
from oca.forms import ProblemaForm, ProblemaForm
from oca.views.decoradores import requiere_registro_sitio

# VH
def main_page(request):
    variables = RequestContext(request,{})
    return render_to_response('main_page.html',variables)



@login_required        
def contest_page(request, id):
    try:
        contest=Competencia.objects.get(id=id)
    except :
        raise Http404
    print 'Pendiente', contest.is_pending()
    print 'Activa', contest.is_active()
    print 'Pasada', contest.is_old()
    user = request.user
    registered = is_registered_to_contest(contest, user)
    print 'Registrado', registered
    problemas = contest.problemas
    info=[]#sucks fix
    time=0
    playing = False
    if (registered and contest.is_active()):
        soluciones = [solucion.problema for solucion in Solucion.objects.filter(participante=user, competencia=contest)]
        for problema in problemas:
            info.append((problema,problema.get_puntaje(contest),not problema in soluciones)) # para saber si el problema fue abierto

        time = lef_time(contest, user)
        playing = time > 0  # registered, active and  has time
    else:
        info = contest.problemas
    has_time = time > 0
    variables = RequestContext(request, {'contest': contest, 'user_':{'registered':registered, 'playing': playing, 'has_time':has_time,
                                                                      'time': time}, 'problems':problemas, 'problemas':info})

    return render_to_response('contest/contest_page.html', variables)
#TODO CUANDO YA PARTICIPO PUEDE VER LO Q HIZO :D ;)


@login_required
def abrio_problema(competencia, problema, usuario):
    try:
        Solucion.objects.get(participante=usuario, problema=problema, competencia=competencia)
        return True
    except:
        return False


@login_required
def register_to_contest(request, idcontest):
    contest = get_object_or_404(Competencia, id=idcontest)
    if (request.user in contest.participantes.all()):
        message = 'Ya se encuentra registrado en la competencia'
        print message
    else:
        print 'asdfsadfsa'
        contest.participantes.add(request.user)
        contest.save()
        message = 'Registro Satisfactorio'
    #variables = RequestContext(request, 'message':message)
    return HttpResponseRedirect('contest/%s/'%idcontest)

@login_required
#requiere registro competencia
def unregister_to_contest(request, idcontest):
    contest = get_object_or_404(Competencia, id=idcontest)
    if request.user in contest.participantes.all(): #probablemente con el decorador muera esto
        contest.participantes.remove(request.user)
        message=''
    else:
        message=''
    return HttpResponseRedirect('contest/%s'%idcontest)

def user_page(request, username):
    user = get_object_or_404(User, username=username)    
    variables = RequestContext(request,{'username':username})
    return render_to_response('user_page.html', variables)

@login_required
def open_problem(request, idcontest, idproblem):
    contest = get_object_or_404(Competencia, id=idcontest)
    problem = get_object_or_404(Problema, id=idproblem)
    time = lef_time(contest, request.user)
    if (time<0):
        return render_to_response('algo.html',{})
    for_view = False
    try:
        solution=Solucion.objects.get(participante=request.user, competencia=contest, problema=problem)
        for_view=True
        solution.codigo="""<code class="%s"> %s </code>""" % (solution.lenguaje.nombre.lower(), solution.codigo)
        #return HttpResponseRedirect('/contest/%s/' % idcontest)
    except Exception,e :
        
        solution=Solucion.objects.create(tiempo=0, codigo='', puntaje=0, participante=request.user, problema=problem, competencia=contest, lenguaje=contest.lenguajes.all()[0])
    
    tupla = tuple([(leng.id, leng.nombre) for leng in contest.lenguajes.all()])
    formulario = ProblemaForm()
    formulario.fields.get('lenguajes').choices = tupla
    score = problem.get_puntaje(contest)
    variables = RequestContext(request, {'contest':contest, 'problem': problem, 'time': time,
                                         'solution':solution, 'for_view':for_view, 'score': score, 'form':formulario})
    return render_to_response("contest/problem.html", variables)
    #problem = get_object_or_404(Problema, 
    #def list(request):

def paginator(request):
    category = User.objects.all()
    print category
    from django.views.generic import list_detail
    salida= list_detail.object_list(request,
                                    queryset = category,
                                    template_name = 'template.html',
                                    paginate_by = 10,
                                    page = 1,
                                    allow_empty = False,
                                    extra_context = {'category': category})
    print salida
    return salida

def user_profile(request, user_name):
    user = get_object_or_404(User, username = user_name)
    #variables = RequestContext(request, 'user':user, contests: user.competencia_set.all()), '


def estadisticas(user):
    pass

def test(request):
    from pygments.lexers import get_lexer_for_filename
    from pygments import highlight
    from pygments.formatters import HtmlFormatter
    lexer = get_lexer_for_filename("file." + 'java', stripall=True)
    formatter = HtmlFormatter(linenos=True)
    code = """<code class='java'>
         public class Fruta implements Comparable
         {
         public Fruta(){
         }
         public string toString(){
         return "hola mundo";
         }
         }
         </code>
         """
    #code = highlight(code, lexer, formatter)
    return render_to_response('code.html',{'code':code})

# CARLITOX #
def listar_competencias_proximas():
    now = datetime.datetime.now()
    return Competencia.objects.filter(inicio__gte=now)[:5]

def listar_soluciones():
    return Solucion.objects.all()[:5]

def listar_usuarios():
    return User.objects.all()[:5]

# TODO poner el tiempo que ocupo para resolver el problema y acomodas lo de las expresiones regulares
def compile_solution(request, idcontest, idproblem):
    contest = get_object_or_404(Competencia, pk=idcontest)
    problem = get_object_or_404(Problema, pk=idproblem)
    # recuperamos datos necesarios
    user = request.user
    solucion = Solucion.objects.filter(competencia=contest,
                                       participante=user,
                                       problema=problem)
    # si la lista esta vacia se crea una solucion
    # si no la asignamos a solucion pusto que solo puede haber una para 
    # los datos filtrados anteriormente
    if len(solucion) == 1:
        solucion = solucion[0]
    solucion.codigo = request.POST.get('codigo', '')
    lenguajeElejido = request.POST.get('lenguajes', 0)
    lenguajeElejido = get_object_or_404(Lenguaje, pk=lenguajeElejido)
    solucion.lenguaje = lenguajeElejido
    # Busca el compilador y guarda en la solucion los resultados
    compilador = buscar_compilador(lenguajeElejido)
    resultado = compilador.compilar(solucion.codigo, user.username)
    if resultado[0] == 0:
        solucion.compila = True
    else:
        solucion.compila = False
    # TODO: guardar el tiempo que tardo en enviar el codigo para la compilacion
    solucion.save()

    # alistamos todo para mostrar
    dictContext = {'title': _('Problema'),
                   'resultado': resultado}
    return render_to_response("contest/compilado.html", dictContext,
                              context_instance=template.RequestContext(request))

# FIXME: buscar una mejor implementacion de este metodo
def buscar_compilador(lenguaje):
    if lenguaje.nombre == 'Python':
        return PyCompiler()
    elif lenguaje.nombre == 'Java':
        return JavaCompiler()

def execute_solution(request, idcontest, idproblem):
    contest = get_object_or_404(Competencia, pk=idcontest)
    problem = get_object_or_404(Problema, pk=idproblem)
    # recuperamos datos necesarios
    user = request.user
    solucion = Solucion.objects.filter(competencia=contest,
                                       participante=user,
                                       problema=problem)
    # si la lista esta vacia se crea una solucion
    # si no la asignamos a solucion pusto que solo puede haber una para 
    # los datos filtrados anteriormente
    if len(solucion) == 1:
        solucion = solucion[0]
    if solucion.compila:
        # Busca el compilador y guarda en la solucion los resultados
        compilador = buscar_compilador(solucion.lenguaje)
        entrada = request.POST.get('entrada','')
        resultado = compilador.ejecutar(solucion.codigo, entrada, user.username)
    else:
        resultado = (0,_("No puede ejecutar por que no logro compilarse"))
    # alistamos todo para mostrar
    dictContext = {'title': _('Problema'),
                   'resultado': resultado}
    return render_to_response("contest/compilado.html", dictContext,
                              context_instance=template.RequestContext(request))

def subir_codigo(request, idcontest, idproblem):
    if request.method == 'POST':
        contest = get_object_or_404(Competencia, pk=idcontest)
        problem = get_object_or_404(Problema, pk=idproblem)
        # recuperamos datos necesarios
        user = request.user
        solucion = Solucion.objects.filter(competencia=contest,
                                           participante=user,
                                           problema=problem)
        # si la lista esta vacia se crea una solucion
        # si no la asignamos a solucion pusto que solo puede haber una para 
        # los datos filtrados anteriormente
        if len(solucion) == 1:
            solucion = solucion[0]
        solucion.codigo = request.POST.get('codigo', '')
    
        # Busca el compilador y guarda en la solucion los resultados
        compilador = buscar_compilador(solucion.lenguaje)
        resultado = compilador.compilar(solucion.codigo, user.username)
        if resultado[0] == 0:
            solucion.compila = True
        else:
            solucion.compila = False
        # TODO: guardar el tiempo que tardo en enviar el codigo para la compilacion
        solucion.save()

    return HttpResponseRedirect("../../../")